# -*- coding:utf8 -*-

###########################################
# Date: 05/11/11                          #
# Nom: Parallels Intelligences            #
# Copyright 2011: Rigaut Maximilien       #
###########################################
#    This file is part of Parallels Intelligences.
#
#    Adem is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    Parallels Intelligences is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with Adem. If not, see <http://www.gnu.org/licenses/>.
########################################################
# LICENCE                                              #
########################################################

if __name__=='__main__': """
+--------------------------------------------------------------+
| Parallels Intelligences Copyright (C) 2011 Rigaut Maximilien |
|  is distributed in the hope that it will be useful, but      |
|  WITHOUT ANY WARRANTY; without even the implied warranty of  |
|  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.        |
+--------------------------------------------------------------+
"""

class vector(object):
	"A mathematical vector"
	def __init__(self,*z):
		self.coordinates=list(z)
	def __eq__(self, other):
		try:
			return self.coordinates==other.coordinates
		except: pass
		return False
	def __getitem__(self, key): return self.coordinates[key]
	def __setitem__(self, key, value): self.coordinates[key]=value
	def __iter__(self): return self.coordinates
	def __str__(self): return str(self.coordinates)
	def __len__(self): return len(self.coordinates)
	def __add__(self, other): 
		i,temp,mx=0,[],len(self)
		while i<mx:
			temp.append(self[i]+other[i])
			i+=1
		return vector(*temp)
	def __neg__(self):
		temp,i,mx=[],0,len(self)
		while i<mx:
			temp.append(-self[i])
			i+=1
		return self
	def __sub__(self,other):
		i,temp,mx=0,[],len(self)
		while i<mx:
			temp.append(self[i]-other[i])
			i+=1
		return vector(*temp)
	def __mul__(self, other):
		temp,i,mx=[],0,len(self)
		while i<mx:
			temp.append(self[i]*other[i])
			i+=1
		return sum(temp)
	def __rmul__(self, other):
		temp,i,mx=[],0,len(self)
		while i<mx:
			temp.append(self[i]*other)
			i+=1
		return vector(*temp)
	def __idiv__(self, other):
		i,mx=0,len(self)
		while i<mx: self[i],i=self[i]*other,i+1
	def __abs__(self):
		'Beware: Return The n_power of distance not the distance itself'
		temp=[]
		for x in self.coordinates: temp.append(x**2)
		return sum(temp)
	def size(self): return abs(self)**(1/len(self))
	def __cmp__(self,other): return self*other
	def __div__(self, other):
		temp,i,mx=[],0,len(self)
		while i<mx:
			temp.append(1.*self[i]/other)
			i+=1
		return vector(*temp)
	def __idiv__(self, other):
		i,mx=0,len(self)
		while i<mx: self[i],i=self[i]*1./other,i+1
		return self
	def zero(self):
		i,mx=0,len(self)
		while i<mx:
			self[i],i=0,i+1

class fast_vector(vector):
	def __init__(self,*l):
		self.coordinates=list(l)
		self.n=len(l)
		self.sqrt=1./n